package com.gaff.emp.core.datasource.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.gaff.emp.core.datasource.properties.DataSourceProperties;
import com.gaff.emp.core.datasource.properties.DynamicDataSourceProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.List;

/**
 * 配置多数据源
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDataSourceConfig {

    @Autowired
    private DynamicDataSourceProperties properties;

    @Bean
    public DynamicRoutingDataSource dynamicRoutingDataSource() throws Exception {
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
        List<DataSourceProperties> dataSourceProperties = properties.getDataSource();
        List<DruidDataSource> targetDataSources = new ArrayList<>();
        dataSourceProperties.forEach(v -> {
            DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);
            targetDataSources.add(druidDataSource);
        });
        dynamicRoutingDataSource.setTargetDataSources(targetDataSources);
        for (DataSourceProperties properties : dataSourceProperties) {
            executeDdlScript(properties);
        }
        return dynamicRoutingDataSource;
    }

    private void executeDdlScript(DataSourceProperties properties) throws Exception {
        if (!"create".equals(properties.getDdlAuto())) {
            return;
        }
        Class.forName(properties.getDriverClassName());
        String file = "classpath*:/sql/" + properties.getName();
        if (properties.getDriverClassName().contains("h2")) {
            file = file + "-h2*.sql";
        } else if (properties.getDriverClassName().contains("oracle")) {
            file = file + "-oracle*.sql";
        } else if (properties.getDriverClassName().contains("SQLServer")) {
            file = file + "-sqlserver*.sql";
        } else if (properties.getDriverClassName().contains("mysql")) {
            file = file + "-mysql*.sql";
        } else if (properties.getDriverClassName().contains("postgresql")) {
            file = file + "-postgresql*.sql";
        }
        String url = properties.getUrl();
        String username = properties.getUsername();
        String password = properties.getPassword();
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources(file);
        if (resources.length == 0) {
            return;
        }
        Connection connection = DriverManager.getConnection(url, username, password);

        try {
            ScriptRunner runner = new ScriptRunner(connection);
            runner.setSendFullScript(true);
            runner.setAutoCommit(true);
            runner.setLogWriter((PrintWriter) null);
            for (Resource resource : resources) {
                log.info("Create the database script: {}", resource.getURI().toString());
                runner.runScript(new InputStreamReader(resource.getInputStream()));
            }
        } catch (Exception e) {
            log.error("executeDdlScript error", e);
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

}
